﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using eslib.DataRetrievalLib.Matchers;



namespace eslib.nnp5.Waitors
{

    /// <summary>
    /// \r\n命令等待器
    /// </summary>
    public class RNWaitor
    {
        private RNMatcher matcher;

        /// <summary>
        /// 等待对象
        /// </summary>
        private AutoResetEvent waitEvent = new AutoResetEvent(false);

        /// <summary>
        /// 最后一次匹配到的命令
        /// </summary>
        public byte[] lastMatch { get; private set; } = new byte[0];



        public RNWaitor()
        {
            matcher = new RNMatcher();
            matcher.matchEvent += Matcher_matchEvent;
        }





        #region C++版本不需要这两个方法

        /// <summary>
        /// 等待目标字符串(不需要带\r\n结尾),ASCII编码，直到有新命令传入，匹配返回true，匹配失败返回false
        /// </summary>
        /// <param name="target">等待目标</param>
        /// <returns></returns>
        public bool wait(string target)
        {
            return wait(target, Encoding.ASCII);
        }


        /// <summary>
        /// 等待目标字符串(不需要带\r\n结尾)，直到有新命令传入，匹配返回true，匹配失败返回false
        /// </summary>
        /// <param name="target">等待目标</param>
        /// <param name="enc">字符编码</param>
        /// <returns></returns>
        public bool wait(string target, Encoding enc)
        {
            return wait(enc.GetBytes(target));
        }

        #endregion




        /// <summary>
        /// 等待目标字节(不需要带\r\n结尾)，直到有新命令传入，匹配返回true，匹配失败返回false
        /// </summary>
        /// <param name="target">等待目标</param>
        /// <returns></returns>
        public bool wait(byte[] target)
        {
            waitEvent.WaitOne();    //等待Matcher的matchEvent事件（即等待下一个命令到达）

            //运行到这里,lastMatch一定已被赋值
            if (target.Length != lastMatch.Length) return false;        //匹配失败

            for (int i = 0; i < target.Length; i++)     //如果长度不匹配，上一行已经排除
            {
                if (target[i] != lastMatch[i]) return false;        //字符不匹配,false
            }

            return true;        //到达这里，所有字符都匹配
        }

        /// <summary>
        /// 仅等待
        /// </summary>
        public void wait()
        {
            waitEvent.WaitOne();    //等待Matcher的matchEvent事件（即等待下一个命令到达）
        }




        /// <summary>
        /// 字节流进入（通常由串口中断调用）
        /// </summary>
        /// <param name="b"></param>
        public void inStream(byte b)
        {
            matcher.inStream(b);
        }

        /// <summary>
        /// 字节流进入（通常由串口中断调用）
        /// </summary>
        /// <param name="buf"></param>
        public void inStream(byte[] buf)
        {
            matcher.inStream(buf);
        }



        private void Matcher_matchEvent(byte[] buf)
        {
            lastMatch = buf;

            //完成等待
            waitEvent.Set();
        }
    }
}
